// Copyright 2023 Huawei Cloud Computing Technology Co., Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef _EPOLL_MODULES_H_
#define _EPOLL_MODULES_H_

#include <sys/epoll.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/epoll.h> 
#include <netinet/in.h>
#include <sys/prctl.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <thread>
#include <mutex>
#include <map>
#include <vector>

#include "QueueModule.h"
#include "SocketServer.h"
#include "CommonMaster.h"

namespace master
{
static const int EPOLL_MAX_EVENT = 10240;
static const int EPOLL_WAIT_TIMEOUT = 3000;
static const int EPOLL_RECV_DATA_LEN = 10240;

    typedef enum {
        EV_IDLE, // 空闲状态
        EV_READ, // 读取状态
        EV_WRITE, // 写出状态

    } EpollType;

class EpollModules{

    typedef struct EpollStateS {
        int epollFd;
        struct epoll_event events[EPOLL_MAX_EVENT];
    } EpollStateT;

    typedef struct EpollFdEventS {
        int eventType;
        WriteDataT writeData;
    } EpollFdEventT;

public:

    static EpollModules& GetInstance() {
        static EpollModules gEpollModules;
        return gEpollModules;
    }
    ~EpollModules() = default;

    int Init(uint32_t maxFdNum = EPOLL_MAX_EVENT);

    int AddFd(int watchFd, int eventType, bool isETMode= true);

    int DeleteFd(int watchFd, int eventType);

    int ModifyFd(int watchFd, int eventType, WriteDataT &pWriteData);

    int StoreSendData(uint8_t *inData, uint32_t inLen, int fd, uint16_t cmdCtl, std::string requestId);

    int Run();

    std::shared_ptr<QueueModules> pQueue;
private:
    EpollModules();

    int ReadData(void);

    static void *ReadDataThreadInit(void *pArgc);

    int DealData(void);

    static void *DealDataThreadInit(void *pArgc);

    int WriteData(void);

    static void *WriteDataThreadInit(void *pArgc);

    int CreateThreadInit(void);

    std::string GenerateRequestId();

    EpollStateT epollState;
    EpollFdEventT *fdWEvent;

    bool init;
    bool run;
    uint32_t maxFdNum;

    pthread_t readId;
    pthread_t dealId;
    pthread_t writeId;
};
};

#endif